home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The CICA Windows Explosion!
/
The CICA Windows Explosion! - Disc 2.iso
/
nt
/
ibmsyn.zip
/
SEMFISRB.H
< prev
next >
Wrap
Text File
|
1992-06-16
|
11KB
|
181 lines
/* semfddrb.h */
/*****************************************************************************/
/* NT IBM SDLC Adapter Device Driver: Receive buffer definitions */
/*****************************************************************************/
/*****************************************************************************/
/* */
/* Receive buffer definitions */
/* */
/* For receive, the object of the design is to miss as few frames as possible*/
/* due to interrupt latency. */
/* */
/* For PIO, this simply means that we service receiver at interrupt level */
/* (rather than DPC level) and, because we are controlling the chip, if we */
/* do overrun, we know about it immediately. */
/* */
/* For DMA, we have the vagary of the 8273 continuing to receive until */
/* disabled. Note that DMA only usable for SDLC: for HDLC, we have to be */
/* full-duplex and, with only one DMA channel available, must use PIO. The */
/* design uses the 'carry on receiving' feature of the 8273 by */
/* */
/* - creating 2 buffers that will receive at least 9 SDLC frames (9*269) */
/* - whenever we restart receiver, try to switch to t'other buffer if at all */
/* possible (i.e. if t'other buffer not in use) */
/* - program the 8273 with a receive buffer size of the whole buffer at the */
/* start of aforementioned receive sequence, and let it rip! */
/* - we only need to disable the receiver if it receives more than 8 full */
/* frames worth (which it shouldn't in SDLC). */
/* */
/* Late note: As of NT265, MmAllocateContiguous memory wasn't working for */
/* > 4K. So reduce the rcvdatabuf_size so the whole RCVBUFFARRAY is < 4K. */
/*****************************************************************************/
#define RCVDATABUF_SIZE ((DEFAULT_FRAME_SIZE*7)+20)
/* 7 SDLC frames + final poll */
typedef struct _RCVBUF
{
TRC_NAME Name; /* name for tracing-2 bytes. To make */
/* macros work, always allocate */
struct _RCVBUF * OtherBuffer;
int FramesPut; /* count of entries made in this buf */
/* (includes error frames if they */
/* have to go into the buffer) */
int FramesGot; /* how many frames pulled by Get */
PHYSICAL_ADDRESS DataPhysAddr; /* &Data as physical address */
UCHAR Data [RCVDATABUF_SIZE];
} RCVBUF,
* PRCVBUF,
RCVBUFARRAY[2];
#define RCVBUF_INUSE(bufptr) (bufptr->FramesPut NE bufptr->FramesGot)
#define RCVBUF_INIT(pDX, index) \
{ \
PRCVBUF pRcvBuf = & pDX->RcvInfo.pRcvBufArray[index]; \
pRcvBuf->Name[0] = 'R'; \
pRcvBuf->Name[1] = CAST ('0'+(index),UCHAR); \
ASSERT ((index & 0xFFFE) EQ 0); /* only 0 or 1 allowed */\
pRcvBuf->OtherBuffer = &pDX->RcvInfo.pRcvBufArray[1-(index)]; \
pRcvBuf->FramesPut = 0; \
pRcvBuf->FramesGot = 0; \
pRcvBuf->DataPhysAddr.LowPart = (ULONG) \
& ((CAST(pDX->RcvInfo.RcvBufPhysAddr.LowPart,PRCVBUF))[index].Data[0]);\
pRcvBuf->DataPhysAddr.HighPart= 0L; \
ASSERT ((pRcvBuf->DataPhysAddr.LowPart & ~0xFFFFFF) EQ 0L); \
/* should be within first 24 bits! */\
TRACE_OBJECT(In,pDX->RcvInfo.pRcvBufArray[index]); \
}
/*****************************************************************************/
/* */
/* The RFD (received frame descriptor is created a) at start of day, or b) */
/* after every receive completion. The NowBeingPut RFD describes the RFD we */
/* are receiving into (if receiver active) or will use when Receiver next */
/* activated. It is incomplete: the BufPtr and StartAddr are correct; but */
/* the RcvdDataLength and SDLC* stuff will not be filled in until EORx. */
/* */
/* The RFD array uses the old SNAPS HMOD approach of having the interrupt */
/* side increment NowBeingPut when a frame is correctly received and the */
/* read routines increment NextToGet. */
/* */
/*****************************************************************************/
typedef struct _RFD /* received frame descriptor */
{
#ifdef IBMSYNC_TRACE
TRC_NAME Name;
#endif
RCVBUF * BufPtr; /* pointer to the RCVBUF */
UCHAR * StartAddr; /* &Data[StartIndex] */
short StartIndex; /* index in Data[] of Address byte */
short RcvdDataLength; /* only valid if valid frame for RFD */
/* received. This length is for data */
/* only (as read from chip in bufferd*/
/* mode). User buffer needs 2 extra */
/* bytes for A & C. */
UCHAR SDLCAddressByte;
UCHAR SDLCControlByte;
} RFD;
#define RFDARRAY_SIZE 9
/*****************************************************************************/
/* The RCVINFO stuff is not moved about as a structure: it is collected as a */
/* structure for ease of reference as there is so much of it. */
/*****************************************************************************/
typedef struct _RCVINFO
{
PMDL pRcvMdl;
PRCVBUF pRcvBufArray; /* actually a ptr to RCVBUF [2] */
PHYSICAL_ADDRESS RcvBufPhysAddr; /* -> start of whole RCVBUF array*/
/* not just 'Data' area */
RFD RFDArray [RFDARRAY_SIZE];
short RFDNowBeingPut;
short RFDNextToGet;
} RCVINFO;
#ifdef IBMSYNC_TRACE
#define RFDARRAY_INIT_NAMES(pDX) \
{ \
short i; \
for (i=0; i<RFDARRAY_SIZE; i++) \
{ \
pDX->RcvInfo.RFDArray[i].Name[0] = 'D'; \
pDX->RcvInfo.RFDArray[i].Name[1] = CAST('0'+i, \
UCHAR); \
} \
}
#else
#define RFDARRAY_INIT_NAMES(pDX)
#endif
#define RCVINFO_INIT(pDX) \
{ /* pRcvMdl,pRcvBufArray,PhysAddr set by AllocateDMA*/\
\
RCVBUF_INIT(pDX, 0); \
RCVBUF_INIT(pDX, 1); \
\
pDX->RcvInfo.RFDArray[0].BufPtr = \
&pDX->RcvInfo.pRcvBufArray[0];\
pDX->RcvInfo.RFDArray[0].StartIndex = 0; \
pDX->RcvInfo.RFDArray[0].StartAddr = \
&(pDX->RcvInfo.pRcvBufArray[0].Data[0]);\
pDX->RcvInfo.RFDArray[0].RcvdDataLength = -1; \
/* debug */\
RFDARRAY_INIT_NAMES(pDX); \
\
pDX->RcvInfo.RFDNowBeingPut = 0; \
pDX->RcvInfo.RFDNextToGet = 0; \
\
TRACE_EVENT(InRF); \
}
#define RFD_CAN_GET(pDX) (pDX->RcvInfo.RFDNextToGet NE pDX->RcvInfo.RFDNowBeingPut)
#define RFD_GOT(pDX) /* means: "We have pulled the data, move NextToGet on" */ \
{ \
short *n = &pDX->RcvInfo.RFDNextToGet; \
\
ASSERT(RFD_CAN_GET(pDX)); \
ASSERT(pDX->RcvInfo.RFDArray[*n].RcvdDataLength NE -1); \
\
TRACE_OBJECT(Rg, pDX->RcvInfo.RFDArray[*n]); \
\
TRACE_DWORD (pDX->RcvInfo.RFDArray[*n].StartAddr); \
\
pDX->RcvInfo.RFDArray[*n].BufPtr->FramesGot++; /* may now be able to */\
/* refresh buffer */\
\
*n = CAST((*n + 1) % RFDARRAY_SIZE, short); \
}
#define RFD_PUT(pDX) /* means: "We have put another frames " */\
pDX->RcvInfo.RFDArray[pDX->RcvInfo.RFDNowBeingPut].BufPtr->FramesPut++;